﻿using System;
using System.Windows.Forms;

namespace Library.Util {
	public partial class Nav : UserControl {
		private static readonly object PageIndexChangedEvent = new object();
		private static readonly object ButtonClickEvent = new object();

		public Nav() {
			InitializeComponent();
			txtMaxPage.Text = "1";
			txtPageIndex.Text = "1";
			btnFirst.Click += delegate {
				OnButtonClick(ButtonType.First, btnFirst);
				PageIndex = 1;
				OnPageIndexChanged(EventArgs.Empty);
			};

			btnPreview.Click += delegate {
				OnButtonClick(ButtonType.Preview, btnPreview);
				if (PageIndex > 1)
					PageIndex--;
				OnPageIndexChanged(EventArgs.Empty);
			};

			btnNext.Click += delegate {
				OnButtonClick(ButtonType.Next, btnNext);
				if (PageIndex < MaxPage)
					PageIndex++;
				OnPageIndexChanged(EventArgs.Empty);
			};

			btnLast.Click += delegate {
				OnButtonClick(ButtonType.Last, btnLast);
				PageIndex = MaxPage;
				OnPageIndexChanged(EventArgs.Empty);
			};

			btnFilter.Click += delegate {
				OnButtonClick(ButtonType.Filter, btnFilter);
			};
			btnSave.Click += delegate {
				OnButtonClick(ButtonType.Save, btnSave);
			};
			btnNew.Click += delegate {
				OnButtonClick(ButtonType.New, btnNew);
			};
			btnDelete.Click += delegate {
				OnButtonClick(ButtonType.Delete, btnDelete);
			};
			txtPageIndex.KeyDown += (s, e) => {
				if ((e.KeyData & Keys.Enter) == Keys.Enter) {
					e.Handled = true;
					OnPageIndexChanged(EventArgs.Empty);
				}
			};

			txtRowPerPage.KeyDown += (s, e) => {
				if ((e.KeyData & Keys.Enter) == Keys.Enter) {
					e.Handled = true;
					OnPageIndexChanged(EventArgs.Empty);
				}
			};
		}

		public int MaxPage {
			get { return Int32.Parse(txtMaxPage.Text); }
		}
		public int PageIndex {
			get {
				int pageIndex;
				if (!Int32.TryParse(txtPageIndex.Text.Trim(), out pageIndex)) {
					pageIndex = 1;
				}

				return pageIndex;
			}
			set { txtPageIndex.Text = value.ToString(); }
		}

		public int PageSize {
			get {
				int pageSize;
				if (!Int32.TryParse(txtRowPerPage.Text.Trim(), out pageSize)) {
					pageSize = 30;
				}

				return pageSize;
			}
			set {
				if (value > 0) {
					txtRowPerPage.Text = value.ToString();
				}
			}
		}

		private int _totalItem;

		public int TotalItem {
			get { return _totalItem; }
			set {
				if (value >= 0) {
					_totalItem = value;
					var rows = PageSize;
					var max = _totalItem / rows;
					if (max * rows < _totalItem) max++;
					txtMaxPage.Text = max.ToString();
				} else {
					txtMaxPage.Text = "1";
				}
			}
		}

		private void TxtPageIndexKeyPress(object sender, KeyPressEventArgs e) {
			if (e.KeyChar == 13) {
				e.Handled = true;
				OnAutoSizeChanged(EventArgs.Empty);
			}
		}

		private void TxtRowPerPageKeyPress(object sender, KeyPressEventArgs e) {
			if (e.KeyChar == 13) {
				e.Handled = true;
				OnAutoSizeChanged(EventArgs.Empty);
			}
		}

		protected virtual void OnPageIndexChanged(EventArgs e) {
			var handler = (EventHandler)Events[PageIndexChangedEvent];
			if (handler != null) handler(this, e);
		}

		private void OnButtonClick(ButtonType type, Button button) {
			OnButtonClick(new ButtonClickEventArgs(type, button));
		}

		protected virtual void OnButtonClick(ButtonClickEventArgs e) {
			var handler = (EventHandler<ButtonClickEventArgs>)Events[ButtonClickEvent];
			if (handler != null) {
				handler(this, e);
			}
		}

		public event EventHandler PageIndexChanged {
			add {
				Events.AddHandler(PageIndexChangedEvent, value);
			}
			remove {
				Events.RemoveHandler(PageIndexChangedEvent, value);
			}
		}

		public event EventHandler<ButtonClickEventArgs> ButtonClick {
			add {
				Events.AddHandler(ButtonClickEvent, value);
			}
			remove {
				Events.RemoveHandler(ButtonClickEvent, value);
			}
		}
		public void DisableButton(ButtonType type) {
			var btn = FindButton(type);
			if (btn != null) btn.Enabled = false;
		}
		public void HideButton(ButtonType type) {
			tableLayout.Controls.Remove(FindButton(type));
		}

		protected Button FindButton(ButtonType type) {
			switch (type) {
				case ButtonType.First:
					return btnFirst;
				case ButtonType.Preview:
					return btnPreview;
				case ButtonType.Next:
					return btnNext;
				case ButtonType.Last:
					return btnLast;
				case ButtonType.Filter:
					return btnFilter;
				case ButtonType.New:
					return btnNew;
				case ButtonType.Save:
					return btnSave;
				case ButtonType.Delete:
					return btnDelete;

				default:
					return null;
			}
		}

		public enum ButtonType {
			First, Preview, Next, Last, Filter, New, Save, Delete
		}

		public class ButtonClickEventArgs : EventArgs {
			public ButtonClickEventArgs(ButtonType buttonType, Button button) {
				Type = buttonType;
				Button = button;
			}
			public ButtonType Type { get; private set; }
			public Button Button { get; private set; }
		}

		protected string RowPerPageText {
			get { return lblRowPerPage.Text; }
			set { lblRowPerPage.Text = value; }
		}

	}
}
